package net.blank.ui
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TouchEvent;
	import flash.geom.Rectangle;
	
	import net.blank.ui.core.UIComponent;
	
	/**
	 * 值发生改变
	 */
	[Event(name="change", type="flash.events.Event")]
	
	/**
	 * 滑块
	 * @author blank
	 * 
	 */
	public class Slider extends UIComponent
	{
		use namespace mapable;
		
		/**
		 * 最小值
		 */
		private var _minValue:Number;
		
		/**
		 * 最大值
		 */
		private var _maxValue:Number;
		
		/**
		 * 值
		 */
		private var _value:Number;
		
		/**
		 * 滑块按钮
		 */
		mapable var _sliderButton:Button;
		
		/**
		 * 是否为垂直滑块
		 */
		private var $isVertical:Boolean;
		
		/**
		 * 更新滑块按钮坐标
		 * 
		 */
		private function updateSliderButtonCoordinate():void{
			if ($isVertical){
				_sliderButton.y = (_value - _minValue) / (_maxValue - _minValue) * (height - _sliderButton.height);
			}else{
				_sliderButton.x = (_value - _minValue) / (_maxValue - _minValue) * (width - _sliderButton.width);
			}
		}
		
		/**
		 * 拖动滑块,改变值
		 * @param evt
		 * 
		 */
		private function stage_moveHandler(evt:Event=null):void{
			//以下代码不能使用 _sliderButton 和坐标来计算,因为 Button 的坐标被覆发表的.
			if ($isVertical){
				_value = mouseY / (height - _sliderButton.height) * (_maxValue - _minValue) + _minValue;
			}else{
				_value = mouseX / (width - _sliderButton.width) * (_maxValue - _minValue) + _minValue;
			}
			
			if(_value < _minValue){
				_value=_minValue;
			}else if(_value > _maxValue){
				_value=_maxValue;
			}
			
			if(evt){
				if(evt is MouseEvent){
					MouseEvent(evt).updateAfterEvent();
				}else{
					TouchEvent(evt).updateAfterEvent();
				}
			}
			
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		/**
		 * 在舞台任意位置释放鼠标/触摸,停止滑块拖动.
		 * @param evt
		 * 
		 */
		private function stage_upHandler(evt:Event):void{
			PLATFORM::PC{
				stage.removeEventListener(MouseEvent.MOUSE_MOVE,stage_moveHandler);
				stage.removeEventListener(MouseEvent.MOUSE_UP,stage_upHandler);
			}
			PLATFORM::MOBILE{
				stage.removeEventListener(TouchEvent.TOUCH_MOVE,stage_moveHandler);
				stage.removeEventListener(TouchEvent.TOUCH_END,stage_moveHandler);
			}
			
			_sliderButton.stopDrag();
			stage_moveHandler();
		}
		
		/**
		 * 在滑块上按下鼠标,启动拖动
		 * @param evt
		 * 
		 */
		private function sliderButton_downHandler(evt:Event):void{
			if (_minValue < _maxValue){
				PLATFORM::PC{
					stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_moveHandler);
					stage.addEventListener(MouseEvent.MOUSE_UP, stage_upHandler);
				}
				PLATFORM::MOBILE{
					stage.addEventListener(TouchEvent.TOUCH_MOVE, stage_moveHandler);
					stage.addEventListener(TouchEvent.TOUCH_END, stage_upHandler);
				}
				
				if ($isVertical){
					_sliderButton.startDrag(false, new Rectangle(0, 0, 0, height - _sliderButton.height));
				}else{
					_sliderButton.startDrag(false, new Rectangle(0, 0, width - _sliderButton.width, 0));
				}
			}
		}
		
		/**
		 * 点击滑块底板,改变值
		 * @param evt
		 * 
		 */
		private function clickHandler(evt:Event):void{
			if (evt.target != _sliderButton){
				if ($isVertical){
					_value = (mouseY - (_sliderButton.height >> 1)) / (height - _sliderButton.height) * (_maxValue - _minValue) + _minValue;
				}else{
					_value = (mouseX - (_sliderButton.width >> 1)) / (width - _sliderButton.width) * (_maxValue - _minValue) + _minValue;
				}
				
				dispatchEvent(new Event(Event.CHANGE));
			}
		}
		
		/**
		 * 滑块
		 * 
		 */
		public function Slider(){
			super();
			
			_minValue=0;
			_maxValue=0;
			_value=0;
			
			_sliderButton=new Button();
			addChild(_sliderButton);
			
			PLATFORM::PC{
				_sliderButton.addEventListener(MouseEvent.MOUSE_DOWN,sliderButton_downHandler);
				addEventListener(MouseEvent.CLICK,clickHandler);
			}
			PLATFORM::MOBILE{
				_sliderButton.addEventListener(TouchEvent.TOUCH_BEGIN,sliderButton_downHandler);
				addEventListener(TouchEvent.TOUCH_TAP,clickHandler);
			}
		}
		
		/**
		 * 最小值
		 * @param value
		 * 
		 */
		public function set minValue(value:Number):void{
			if(value != _minValue){
				_minValue=value;
				
				updateSliderButtonCoordinate();
			}
		}
		public function get minValue():Number{
			return _minValue;
		}
		
		/**
		 * 最大值
		 * @param value
		 * 
		 */
		public function set maxValue(value:Number):void{
			if(value != _maxValue){
				_maxValue=value;
				
				updateSliderButtonCoordinate();
			}
		}
		public function get maxValue():Number{
			return _maxValue;
		}
		
		/**
		 * 值
		 * @param v
		 * 
		 */
		public function set value(v:Number):void{
			if(v != _value){
				if(v < _minValue){
					_value=_minValue;
				}else if(v > _maxValue){
					_value=_maxValue;
				}else{
					_value=v;
				}
				
				updateSliderButtonCoordinate();
				
				dispatchEvent(new Event(Event.CHANGE));
			}
		}
		public function get value():Number{
			return _value;
		}
		
		override public function reset():void{
			_minValue=0;
			_maxValue=99;
			_value=0;
			
			if(stage){
				PLATFORM::PC{
					stage.removeEventListener(MouseEvent.MOUSE_MOVE,stage_moveHandler);
					stage.removeEventListener(MouseEvent.MOUSE_UP,stage_upHandler);
				}
				PLATFORM::MOBILE{
					stage.removeEventListener(TouchEvent.TOUCH_MOVE,stage_moveHandler);
					stage.removeEventListener(TouchEvent.TOUCH_END,stage_moveHandler);
				}
			}
			
			if(_sliderButton){
				_sliderButton.stopDrag();
			}
			
			super.reset();
		}
		
		override public function destroy():void{
			reset();
			
			if(_sliderButton){
				PLATFORM::PC{
					_sliderButton.removeEventListener(MouseEvent.MOUSE_DOWN,sliderButton_downHandler);
					removeEventListener(MouseEvent.CLICK,clickHandler);
				}
				PLATFORM::MOBILE{
					_sliderButton.removeEventListener(TouchEvent.TOUCH_BEGIN,sliderButton_downHandler);
					removeEventListener(TouchEvent.TOUCH_TAP,clickHandler);
				}
				
				_sliderButton=null;
			}
			
			super.destroy();
		}
	}
}